<?php
/*
 * @Descripttion: 
 * @version: 1.0
 * @Author: Sam
 * @Date: 2022-03-26 01:16:12
 * @LastEditors: Sam
 * @LastEditTime: 2022-11-18 15:46:05
 */
declare (strict_types=1);

namespace app\admin\middleware;

use app\admin\model\Admin as AdminModel;
use app\admin\model\AuthGroupAccess as AuthGroupAccessModel;
use app\admin\model\AuthRule as AuthRuleModel;
use app\admin\model\AuthRuleAccess;
use app\common\http\ResponseCode;
use app\common\support\Token;
use app\common\traits\ResponseJson;
use tauthz\facade\Enforcer;
use Exception;
use think\exception\HttpException;
use think\Request;
use think\facade\Db;
use Closure;

/*
 * 权限检测
 *
 * @create 2020-10-28
 * @author deatil
 */

class Permission
{
    use ResponseJson;


    public function handle($request, Closure $next)
    {
        if (!$this->shouldPassThrough($request)) {
            try {
                $this->permissionCheck();
            } catch (HttpException $e) {
                return $this->error($e->getMessage(), $e->getStatusCode());
            }
        }
        $this->recode_admin_log();
        return $next($request);
    }

    /**
     * 记录管理员操作日志
     * @return void
     * @author Sam
     * @date 2022-05-11
     */
    public function recode_admin_log(){
        try {
            $admin_name = (new Token())->withRequestToken()->getClaim('admin_name') ?? '';
            $admin_id = (new Token())->withRequestToken()->getClaim('admin_id') ?? '';
            $requestUrl    = request()->rule()->getName() ?? '';
            $requestMethod = request()->method() ?? '';
            $url_name      = Db::name('auth_rule')->where('slug',$requestUrl)->cache('rule_title:'.$requestUrl)->value('title') ?? '';
          if(request()->isPost() && !in_array(request()->rule()->getName(),config('extra.auth.token_filter'))) {
            Db::name('admin_log')->insert([
                'title' => $url_name,
                'url'   => $requestUrl,
                'method' => $requestMethod,
                'admin_name' => $admin_name,
                'admin_id'   => $admin_id,
                'admin_ip'  => request()->ip(),
                'add_time' => date('Y-m-d H:i:s')
            ]);
          } 
        } catch (\Exception $e) {
        }
    }
    /*
     * 权限检测
     */
    public function permissionCheck()
    {
        try {
            $adminId = (new Token())->withRequestToken()->getClaim('admin_id') ?? '';
        } catch (Exception $e) {
            throw new HttpException(ResponseCode::AUTH_ERROR, $e->getMessage());
        }
        $requestUrl    = request()->rule()->getName() ?? '';
        $requestMethod = request()->method() ?? '';
        $group_id = AuthGroupAccessModel::where('admin_id', $adminId)->column('group_id'); //获取当前管理员所在的分组
        $rule_ids = AuthRuleAccess::where('group_id','in', $group_id)->column('rule_id');
        $access = AuthRuleModel::field('slug')
            ->whereIn('id', $rule_ids)
            ->select()
            ->toArray();
        $slug   = array_column($access, 'slug');
        if(!in_array($requestUrl,$slug)){
            throw new HttpException(ResponseCode::AUTH_ERROR, '你没有访问权限');
        }
        // if (!Enforcer::enforce($adminId, $requestUrl, $requestMethod)) {
        //     throw new HttpException(ResponseCode::AUTH_ERROR, '你没有访问权限');
        // }
    }

    /**
     * @return bool
     */
    protected function shouldPassThrough($request): bool
    {
        // permission_filter
        if (in_array(request()->rule()->getName(), config('extra.auth.permission_filter')) ||
            app('auth-admin')->isRoot()) {
            return true;
        }

        return false;
    }
}
